package Java实验.实验二.小学学生信息管理系统第二版;

import java.io.*;
import java.util.*;
/**
 * @ClassName StudentApp
 * @Description 对小学信息管理系统的一个功能实现
 * 主要添加了将学生信息存于文件中和从文件读取学生信息方法
 * @Author 李明忠
 * @Date 2024/11/20 12:43
 * @Version 2.0
 */
public class StudentApp {

/*----------------------学生信息表的创建----------------------------*/
    //创建学生信息表
    static Student[] ss = new Student[10];
/*-----------------------END------------------------------*/

/*--------------------------------父类功能的欢迎界面-----------------------------------*/
    /**
     * @description: 父类功能的欢迎界面
     * @param: null
     * @return: void
     */
    public void welcomeOfFather() {
        /**
         * 1.初始化学生信息
         * 2.显示学生信息
         *  2.1 显示所有学生信息
         *  2.2 仅显示学生身体质量信息
         * 3.查询指定学生信息
         *  3.1 按学号
         *  3.2 按姓名
         *  3.3 按班级
         * 4.查询班级平均分
         *  4.1 语文
         *  4.2 数学
         *  4.3 总分
         * 5.求不及格的学生
         *  5.1 语文不及格(按班级)
         *  5.2 数学不及格(按班级)
         *  5.3 总分不及格(按班级)
         * 6.修改学生成绩
         *  6.1 按学号修改语文成绩
         *  6.2 按学号修改数学成绩
         * 7.考试系统
         *  7.1 统一考试成绩自动录入(Random)
         *  7.2 统一考试成绩手动录入(Scanner)
         */
        System.out.println("\n----小学学生信息管理系统1.0----");
        System.out.println("请选择下列功能(选0退出系统):");
        //父功能1
        System.out.println("----1:显示学生信息(父功能)：");
        //父功能2
        System.out.println("----2:查询指定学生信息(父功能)：");
        //父功能3
        System.out.println("----3:查询(求)班级平均分(父功能)：");
        //父功能4
        System.out.println("----4:求不及格的学生(父功能)：");
        //父功能5
        System.out.println("----5:修改学生成绩(父功能)：");
        //父功能6
        System.out.println("----6:考试系统(父功能)：");
        System.out.println("----0:退出系统！");
        System.out.println("--------------------------");
    }
/*---------------------------------------END--------------------------------------------*/

/*----------------------------以下1--6个方法是五个父功能当中的子功能欢迎界面-------------------*/
    /** 
     * @description:  1显示学生信息欢迎界面
     *  作用： 1.1 显示所有学生信息 
     *        1.2 仅显示学生身体质量信息 
     * @param: null
     * @return: void
     */
    public void welcomeShow(){
        System.out.println("\n====欢迎来到显示学生信息界面====");
        System.out.println("请选择下列功能(选0回到首页):");
        System.out.println("****1:显示所有学生信息****");
        System.out.println("****2:仅显示学生身体质量信息****");
        System.out.println("****0:回到首页！！****");
        System.out.println("=======================");
    }
    
    /** 
     * @description: 2查询指定学生信息欢迎界面
     * 作用：2.1 按学号查询
     *      2.2 按姓名查询
     *      2.3 按班级查询
     * @param: null
     * @return: void
     */
    public void welcomeSelStuInfo(){
        System.out.println("\n====欢迎来到查询学生信息界面====");
        System.out.println("请选择下列功能(选0回到首页):");
        System.out.println("####1:按学号查询学生信息####");
        System.out.println("####2:按姓名查询查询学生信息####");
        System.out.println("####3:按班级查询学生信息####");
        System.out.println("####0:回到首页！！####");
        System.out.println("=======================");
    }
    
    /** 
     * @description: 3求班级平均分欢迎界面
     * 作用：3.1 求语文平均分
     *      3.2 求数学平均分
     *      3.3 求总分平均分
     * @param: null
     * @return: void
     */
    public void welcomeSelStuAverage(){
        System.out.println("\n====欢迎来到求班级平均分界面====");
        System.out.println("请选择下列功能(选0回到首页):");
        System.out.println("////1:求语文成绩平均分////");
        System.out.println("////2:求数学成绩平均分////");
        System.out.println("////3:求总分成绩平均分////");
        System.out.println("////0:回到首页！！////");
        System.out.println("=======================");
    }
    
    /** 
     * @description: 4求不及格的学生人数并显示欢迎界面
     * 作用： 4.1 语文不及格
     *       4.2 数学不及格
     *       4.3 总分不及格
     * @param: null
     * @return: 
     * @author Oneby
     */
    public void welcomeStuFail(){
        System.out.println("\n====欢迎来到求不及格的学生人数界面====");
        System.out.println("请选择下列功能(选0回到首页):");
        System.out.println("----1:求语文不及格----");
        System.out.println("----2:求数学不及格----");
        System.out.println("----3:求总分不及格----");
        System.out.println("----0:回到首页！！----");
        System.out.println("=======================");
    }

    /**
     * @description: 5修改学生成绩欢迎界面
     * 作用： 5.1 按学号修改语文成绩
     *       5.2 按学号修改数学成绩
     * @param: null
     * @return:
     * @author Oneby
     */
    public void welcomeUpdate(){
        System.out.println("\n====欢迎来到修改学生成绩界面====");
        System.out.println("请选择下列功能(选0回到首页):");
        System.out.println("====1:按学号修改语文成绩====");
        System.out.println("====2:按学号修改数学成绩====");
        System.out.println("====0:回到首页！！====");
        System.out.println("=======================");
    }

    /**
     * @description:  6显示考试系统欢迎界面
     *  作用： 6.1 统一考试成绩自动录入(Random)
     *        6.2 统一考试成绩手动录入(Scanner)
     * @param: null
     * @return: void
     */
    public void welcomeExamSystem(){
        System.out.println("\n====欢迎来到考试系统界面====");
        System.out.println("请选择下列功能(选0回到首页):");
        System.out.println("^^^^1:统一考试成绩自动录入(Random)^^^^");
        System.out.println("^^^^2:统一考试成绩手动录入(Scanner)");
        System.out.println("^^^^0:回到首页！！^^^^");
        System.out.println("=======================");
    }

    /**
     * 总结：写了六个欢迎界面感觉相似代码很多冗余较高，希望老师给一点建议
     */
/*---------------------------------------END--------------------------------------------*/


/*--------------------------------StudentApp无参构造-----------------------------------*/

    /**
     * @description: StudentApp无参构造
     * @param: null
     * @return: 无
     */
    public StudentApp() {
    }
/*---------------------------------------END--------------------------------------------*/


/*--------------------------------以下是实现初始化-----------------------------------*/

    /**
     * @description: 1.初始化学生信息
     * @param: null
     * @return: void
     */
     public void init(String path){
         //1.初始化基本信息(不包括学生身体质量)
         ss[0] =new Student("23011", "李明", "男", "2010-01-11", "一年级1班", "长沙");
         ss[1] =new Student("23012", "小红", "女", "2011-02-12", "二年级2班", "合肥");
         ss[2] =new Student("23013", "小刚", "男", "2012-03-13", "三年级3班", "福州");
         ss[3] =new Student("23014", "小丽", "女", "2013-04-14", "一年级1班", "南宁");
         ss[4] =new Student("23015", "小强", "男", "2014-05-15", "一年级5班", "贵阳");
         ss[5] =new Student("23016", "小美", "女", "2015-06-16", "五年级6班", "昆明");
         ss[6] =new Student("23017", "李明", "男", "2016-07-17", "三年级7班", "哈尔滨");
         ss[7] =new Student("23018", "小琳", "女", "2017-08-18", "四年级8班", "长春");
         ss[8] =new Student("23019", "小宇", "男", "2018-09-19", "一年级9班", "沈阳");
         ss[9] =new Student("23020", "小悦", "女", "2019-10-20", "六年级10班", "大连");
         //2.初始化学生身体质量
         Random r=new Random();
         for (int i = 0; i < ss.length; i++) {
             /*
              * 随机产生40到100的数(体重)
              * r.nextInt(n)产生0到n-1的随机数
              * weight [40~100]
              * 减加法 [40,100]-40=[0,60]+40=r.nextInt(61)+40
              */
             double weight=r.nextInt(61)+40;//产生随机体重(50-100)
             ss[i].setWeight(weight);
             /*
              * 随机产生1.55到2.0的数(身高)
              * r.nextDouble()产生0.0到1.0(不包括)的随机double数
              * 若想产生1.55到2.0：
              * double min = 1.55;
              * double max = 2.0;
              * double height = min + r.nextDouble() * (max - min);
              */
             double min = 1.55;
             double max = 2.0;
             double height = min + r.nextDouble() * (max - min);//产生随机身高(1.55-2.0)
             ss[i].setHeight(height);
             //BMI初始化
             ss[i].setBMI();//必须写在最后面(因为只有先有height和weight才有它)
         }
         //2将这些个对象序列化于文件中
         try (
                 //3创建一个对象输出流包装原始字节输出流对象
                 ObjectOutputStream oos=
                         new ObjectOutputStream(new FileOutputStream(path));
         ){
             //4开始序列化
             for(int i=0;i<ss.length;i++){
                 oos.writeObject(ss[i]);
             }
             System.out.println("\n学生基本信息存于文件成功(除了学生成绩和身体质量)！！");
         } catch (Exception e) {
             e.printStackTrace();
         }

         System.out.println("学生身体质量初始化成功(除了学生成绩)！！");
     }
/*---------------------------------------END--------------------------------------------*/

/*------------------------------------读学生信息-----------------------------------------*/
    public void readStudentInfoForFile(String desPath){
        try (
                //1创建一个对象输入流包装原来的字节输入流对象
                ObjectInputStream ois=new ObjectInputStream(new FileInputStream(desPath));
                ){
            //2反序列化
            for(int i=0;i<ss.length;i++){
                ss[i]=(Student)ois.readObject();
            }
            System.out.println("反序列化成功！！！");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
/*---------------------------------------END--------------------------------------------*/

/*--------------------------------以下方法都是实现子功能的方法-----------------------------------*/
     /**
      * @description: 2.1显示所有学生信息
      * @param: null
      * @return: void
      */
     public void showAllStudents(){
         System.out.println("所有学生信息如下");
         for (int i = 0; i < ss.length; i++) {
             ss[i].showInfo();
         }
     }

     /**
      * @description: 2.2 仅显示所有学生身体质量信息
      * @param: null
      * @return: void
      */
     public void showAllStudentsBodyMass(){
         System.out.println("所有学生身体质量信息如下");
         for (int i = 0; i < ss.length; i++) {
             ss[i].displayStuPhyInfo();
         }
     }


    /**
     * @description: 3.1查询学生信息(按学号) 根据输入的学号查询对应学生信息
     * @param: num-学号
     * @return: Student
     */
    private Student getStudentByNum(String num) {
        Student s=null;
        for (int i = 0; i < ss.length; i++) {
            if (num.equals(ss[i].num)) {
                return ss[i];
            }
        }
        return s;//找不到返回空
    }

    /**
     * @description: 3.2查询学生信息(按姓名) 根据姓名查询对应学生
     * 如果找到 哪怕是同名的也要输出 ss[i].showInfo();
     * 由于在调用处去判断有无此人，因此我们需要在本函数中判断即可
     * 使用boolean作为是否有学生的判断有就输出学生信息;如果没有此人输出提示语句
     * @param: String name--姓名
     * @return: void 如果找不到(没有这个学生)那么返回输出"查无此人，请重新输入学生姓名！"
     */
    //扩充：
    public void getStudentByName(String name){
        boolean flag=false;//判断有无此学生
        int n=0;//用于记录同名学生人数
        for (int i = 0; i < ss.length; i++) {
            if(name.equals(ss[i].name)){
                flag=true;//有对应学生
                System.out.println("\n查询到第"+(++n)+"个名字为 “"+name+"” 的学生信息如下：");
                ss[i].showInfo();//找到就直接输出
            }
        }
        if(!flag){
            System.out.println("查无此人，请重新输入学生姓名！");//如果找不到(没有这个学生)那么返回null
        }
        /**
         * 总结：本方法体中不用if-else
         * 而是用flag判断是避免没有找到学生打印出的提示会变多
         * 1 如果用if-else
         * for (int i = 0; i < ss.length; i++) {
         *       if(name.equals(ss[i].name)){
         *           flag=true;//有对应学生
         *           System.out.println("\n查询到第"+(++n)+"个名字为 “"+name+"” 的学生信息如下：");
         *           ss[i].showInfo();//找到就直接输出
         *       }else{
         *         System.out.println("查无此人，请重新输入学生姓名！");
         *       }
         *   }
         * 如果找不到对应学生那么就会输出10个：查无此人，请重新输入学生姓名！
         * 我们不希望这个结果
         * 2 使用标记位思想
         * boolean flag=false;//判断有无此学生
         *    int n=0;//用于记录同名学生人数
         *    for (int i = 0; i < ss.length; i++) {
         *        if(name.equals(ss[i].name)){
         *            flag=true;//有对应学生
         *            System.out.println("\n查询到第"+(++n)+"个名字为 “"+name+"” 的学生信息如下：");
         *            ss[i].showInfo();//找到就直接输出
         *        }
         *    }
         *    if(!flag){
         *        System.out.println("查无此人，请重新输入学生姓名！");//如果找不到(没有这个学生)那么返回null
         *    }
         * 此时如果我们找不到学生那么它就只是显示一个这个样的提示信息
         */
    }

    /**
     * @description: 3.3 按班级查询学生信息
     * 方法基本与getStudentByName()一样 在本方法内部判断有无该班级
     * 有所传参数的班级就输出学生信息 无就提示查询输入
     * @param: String MyClass--传入班级
     * @return: void
     */
    public void getStudentByClass(String myClass){
        boolean flag=false;//判断有无对应班级
        int n=0;//由于记录同班人数(配合输出用的:++n)
        for (int i = 0; i < ss.length; i++) {
            if(ss[i].myClass.equals(myClass)){//总结字符串的比较只能用equals
                flag=true;//有对应班级
                System.out.println("\n查询到"+myClass+"的第"+(++n)+"个学生如下:");
                ss[i].showInfo();
            }
        }
        if(!flag){//如果没有对应班级就提示重新输入
            System.out.println("没有对应的班级，请重新输入！！");
        }
    }

    /**
     * @description: 4.1 求该班级语文平均分(通过指定班级获得该班学生语文平均成绩)
     * @param: String myClass--班级
     * @return: double 语文平均分 和 小于0的数-1
     * 如果返回非-1那么说明统计正确
     * 如果返回-1那么说明由于没有该班级导致统计错误
     * @author Oneby
     */
    public double getClassChineseAverage(String myClass){
        double count=0.0;//所有语文成绩之和
        double chineseAverage=0.0;//语文平均成绩
        int num=0;//同班级人数
        boolean flag=false;//有无指定班级(是否为合法班级)
        for (int i = 0; i < ss.length; i++) {
            if(myClass.equals(ss[i].myClass)){//找到指定班级
                flag=true;//合法班级
                num++;
                count+=ss[i].getChineseScore();//对同班级语文成绩求和
            }
        }
        if(!flag){//如果是不合法班级返回一个小于0的数
            return -1;
        }
        else{//如果是合法班级返回语文平均成绩
            chineseAverage=count/num;
            return chineseAverage;
        }
    }

    /**
     * @description: 4.2 求该班级数学平均分(通过指定班级获得该班学生数学平均成绩)
     * @param: String myClass--班级
     * @return: double 数学平均分 和 小于0的数-1
     * 如果返回非-1那么说明统计正确
     * 如果返回-1那么说明由于没有该班级导致统计错误
     * @author Oneby
     */

    public double getClassMathAverage(String myClass){
        double count=0.0;//所有数学成绩之和
        double mathAverage=0.0;//数学平均成绩
        int num=0;//同班级人数
        boolean flag=false;//有无指定班级(是否为合法班级)
        for (int i = 0; i < ss.length; i++) {
            if(myClass.equals(ss[i].myClass)){//找到指定班级
                flag=true;//合法班级
                num++;
                count+=ss[i].getMathScore();//对同班级数学成绩求和
            }
        }
        if(!flag){//如果是不合法班级返回一个小于0的数
            return -1;
        }
        else{//如果是合法班级返回数学平均成绩
            mathAverage=count/num;
            return mathAverage;
        }
    }

    /**
     * @description: 4.3 求该班级总分平均分(通过指定班级获得该班总分的平均成绩)
     * @param: String myClass--班级
     * @return: double 班级总分平均分 和 小于0的数-1
     * 如果返回非-1那么说明统计正确
     * 如果返回-1那么说明由于没有该班级导致统计错误
     */
    public double getClassTotalAverage(String myClass){
        double count=0.0;//所有总分(语文+数学)成绩之和
        double TotalAverage=0.0;//总分(语文+数学)平均成绩
        int num=0;//同班级人数
        boolean flag=false;//有无指定班级(是否为合法班级)
        for (int i = 0; i < ss.length; i++) {
            if(myClass.equals(ss[i].myClass)){//找到指定班级
                flag=true;//合法班级
                num++;
                count+=ss[i].getTotalScore();//对同班级总分(语文+数学)成绩求和
            }
        }
        if(!flag){//如果是不合法班级返回一个小于0的数
            return -1;
        }
        else{//如果是合法班级返回总分(语文+数学)平均成绩
            TotalAverage=count/num;
            return TotalAverage;
        }
    }

    /**
     * @description: 5.1 求语文成绩不及格的人数和学生信息
     * (通过指定班级获得该班语文成绩不及格的人数)
     * @param: String myClass--班级
     * @return: int
     * 1.班级不合法 return -1
     * 2.班级合法但是没有不及格的 return 0
     * 3.班级合法且有不及格的 return count
     */
    public int getStudentByChineseFail(String myClass){
        int count=0;//统计本班语文成绩不及格人数
        boolean flag1=false;//是否为合法班级
        boolean flag2=false;//有无语文<60分的学生
        for (int i = 0; i < ss.length; i++) {
            if(myClass.equals(ss[i].myClass)){//找到指定班级
                flag1=true;//合法班级
                if(ss[i].getChineseScore()<60){//在指定班级找到语文成绩<60
                    flag2=true;//有语文成绩小于60分的
                    ++count;
                    System.out.println("\n查询到"+myClass+"的第"+(count)+"个语文不及格学生如下:");
                    ss[i].showInfo();//打印语文不及格学生的信息
                }
            }
        }
        if(!flag1){//如果是不合法班级
            return -1;
        }else{//否则flag1==true
            //flag2==true
            if(flag2){ //(flag1==true&&flag2==true)
                return count;//班级合法但是没有不及格的
            }else{//否则flag2==false
                //本质(flag1==true&&flag2==false)
                return 0;//班级合法且有不及格的
            }
        }
    }

    /**
     * @description: 5.2 求数学成绩不及格的人数和学生信息
     * (通过指定班级获得该班数学成绩不及格的人数)
     * @param: String myClass--班级
     * @return: int
     * 1.班级不合法 return -1
     * 2.班级合法但是没有不及格的 return 0
     * 3.班级合法且有不及格的 return count
     */
    public int getStudentByMathFail(String myClass){
        int count=0;//统计本班数学成绩不及格人数
        boolean flag1=false;//是否为合法班级
        boolean flag2=false;//有无数学<60分的学生
        for (int i = 0; i < ss.length; i++) {
            if(myClass.equals(ss[i].myClass)){//找到指定班级
                flag1=true;//合法班级
                if(ss[i].getMathScore()<60){//在指定班级找到数学成绩<60
                    flag2=true;//有数学成绩小于60分的
                    ++count;
                    System.out.println("\n查询到"+myClass+"的第"+(count)+"个数学不及格学生如下:");
                    ss[i].showInfo();//打印数学不及格学生的信息
                }
            }
        }
        if(!flag1){//如果是不合法班级
            return -1;
        }else{//否则flag1==true
            //flag2==true
            if(flag2){ //(flag1==true&&flag2==true)
                return count;//班级合法但是没有不及格的
            }else{//否则flag2==false
                //本质(flag1==true&&flag2==false)
                return 0;//班级合法且有不及格的
            }
        }
    }

    /**
     * @description: 5.3 求总分(语文+数学)不及格的人数和学生信息
     * (通过指定班级获得该班总分(语文+数学)不及格的人数)
     * @param: String myClass--班级
     * @return: int
     * 1.班级不合法 return -1
     * 2.班级合法但是没有不及格的 return 0
     * 3.班级合法且有不及格的 return count
     */
    public int getStudentByTotalFail(String myClass){
        int count=0;//统计本班总分(语文+数学)不及格人数
        boolean flag1=false;//是否为合法班级
        boolean flag2=false;//有无总分(语文+数学)<120分的学生
        for (int i = 0; i < ss.length; i++) {
            if(myClass.equals(ss[i].myClass)){//找到指定班级
                flag1=true;//合法班级
                if(ss[i].getTotalScore()<120){//在指定班级找到总分(语文+数学)<60
                    flag2=true;//有总分(语文+数学)小于120分的
                    ++count;
                    System.out.println("\n查询到"+myClass+"的第"+(count)+"个总分不及格学生如下:");
                    ss[i].showInfo();//打印总分(语文+数学)不及格学生的信息
                }
            }
        }
        if(!flag1){//如果是不合法班级
            return -1;
        }else{//否则flag1==true
            //flag2==true
            if(flag2){ //(flag1==true&&flag2==true)
                return count;//班级合法但是没有不及格的
            }else{//否则flag2==false
                //本质(flag1==true&&flag2==false)
                return 0;//班级合法且有不及格的
            }
        }
    }

    /**
     * @description: 6.1修改指定学号对应的学生的语文成绩
     * @param: num-学号 用于找到该学号对应的学生
     *         chineseScore-语文成绩 用于替换被修改值
     * @return: int 如果返回一个合法下标==>说明修改成功
     *使用返回下标的好处是我们可以在调用处测试时输出数组中下标对应的学生更改新信息
     *                  如果返回-1==>说明修改失败或者是没有指定学生
     */
    public int updateStudentChineseScoreByNum(String num,double chineseScore){
        int index=-1;//判断是否修改成功并且存放被修改学生所存数组下标
        for (int i = 0; i < ss.length; i++) {
            if(num.equals(ss[i].num)){
                ss[i].setChineseScore(chineseScore);//修改语文成绩
                //总结：修改后一定把总分重新赋值一下（这个bug很关键）
                ss[i].setTotalScore(ss[i].getMathScore()+chineseScore);//修复bug:总分重置
                index=i;
            }
        }
        return index;
    }

    /**
     * @description: 6.2修改指定学号对应的学生的数学成绩
     * @param: num-学号 用于找到该学号对应的学生
     *         mathScore-数学成绩 用于替换被修改值
     * @return: int 如果返回一个合法下标==>说明修改成功
     * 使用返回下标的好处是我们可以在调用处测试时输出数组中下标对应的学生更改新信息
     *              如果返回-1==>说明修改失败或者是没有指定学生
     */
    public int updateStudentMathScoreByNum(String num,double mathScore){
        int index=-1;//判断是否修改成功并且存放被修改学生所存数组下标
        for (int i = 0; i < ss.length; i++) {
            if(num.equals(ss[i].num)){
                ss[i].setMathScore(mathScore);//修改数学成绩
                //修改后一定把总分重新赋值一下（这个bug很关键）
                ss[i].setTotalScore(ss[i].getChineseScore()+mathScore);//修复bug:总分重置
                index=i;
            }
        }
        return index;//修改不成功返回-1(小于0)  修改成功返回>=0的索引index
    }

    /**
     * 总结:使用标记位(boolean flag=false)思想相当重要可以提高效率
     */
    /*-----------------------------------END------------------------------------*/

/*-----------------以下1--6个方法是对主菜单switch case中测试父功能中子功能实现的封装方法---------------*/
    /**
     * @description: ----1显示学生信息的父功能方法
     * 函数体实现子功能实现菜单:
     *  1.1 显示所有学生信息
     *  1.2 仅显示学生身体质量信
     * @param: null
     * @return: void
     */
    public void showAllStudentsFather(){
        Scanner sc = new Scanner(System.in);
        /*
        *总结：在所有的子功能界面中
        *得使用一个boolean类型变量flag判断是否退出while循环
        *这一步是相当有必要的
        */
        //显示学生信息菜单
        while(true){//使用while循环实现多次选择
            boolean flag=false;//用于判断是否跳出循环(一般初始化都为false)
            welcomeShow();//配合显示信息欢迎界面给用户提供提示服务
            int ch=sc.nextInt();//输入一个整数选择相应的操作
            switch (ch){
                case 1:
                    //2.1 显示所有学生信息
                    showAllStudents();
                    break;
                case 2:
                    //2.2 仅显示所有学生身体质量信息
                    showAllStudentsBodyMass();
                    break;
                case 0:
                    flag=true;//确定结束该子功能界面
                    break;
                default:
                    System.out.println("输入错误，请选择正确的功能序号!");
            }
            if(flag){//如果flag为真那么就跳出while回到主菜单中的switch中去(关键)
                System.out.println("已退出显示学生信息界面,回到首页！！");
                break;
            }
        }
    }



    /**
     * @description: ----2:查询指定学生信息的父功能方法
     * 函数体实现子功能实现菜单:
     * 2.1 按学号
     * 2.2 按姓名
     * 2.3 按班级
     * @param: null
     * @return: void
     */
    public void getStudentFather(){
        Scanner sc = new Scanner(System.in);
        //查询指定学生菜单
        while(true){//使用while循环实现多次选择
            boolean flag=false;//用于判断是否跳出循环(一般初始化都为false)
            welcomeSelStuInfo();//配合查询指定学生信息欢迎界面给用户提供提示服务
            int ch=sc.nextInt();//输入一个整数选择相应的操作
            switch (ch){
                case 1:
                    //2.1 按学号查询
                    System.out.println("请输入要查询的学生学号：");
                    String num1 = sc.next();
                    Student s = getStudentByNum(num1);//学生数组中存的是每个学生的地址(引用)所以类型为Student
                    if (s == null) {
                        System.out.println("查无此人，请重新输入学号！");
                    } else {
                        System.out.println("查询到以下学生信息：");
                        s.showInfo();
                    }
                    break;
                case 2:
                    //2.2 按姓名查询
                    System.out.println("请输入要查询的学生姓名：");
                    //String name1=sc.nextLine();
                    String name1=sc.next();
                    getStudentByName(name1);
                    /**
                     * 总结
                     * 案列可能出现的问题：
                     * 如果使用String name1=sc.nextLine();
                     * Student s2 = getStudentByNum(name1);
                     * if (s2 == null) {
                     * System.out.println("查无此人，请重新输入学号！");
                     * }
                     * 输入3之时
                     * 请输入要查询的学生姓名：
                     * 查无此人，请重新输入学号！
                     * 此问题是由于用了nextLine()造成的输入问题
                     * 解决办法就是改用next()即可
                     * String name1=sc.next();
                     * Student s2 = getStudentByNum(name1);
                     * if (s2 == null) {
                     * System.out.println("查无此人，请重新输入学号！");
                     * }
                     */
                    break;
                case 3:
                    //2.3 按班级查询
                    System.out.println("请输入要查询的班级(例如:一年级1班)：");
                    String myClass1=sc.next();
                    getStudentByClass(myClass1);
                    break;
                case 0:
                    flag=true;//确定结束该子功能界面
                    break;
                default:
                    System.out.println("输入错误，请选择正确的功能序号!");
            }
            if(flag){//如果flag为真那么就跳出while回到主菜单中的switch中去(关键)
                System.out.println("已退出查询学生信息界面,回到首页！！");
                break;
            }
        }
    }



    /**
     * @description: 3:求班级平均分的父功能方法
     *函数体实现子功能实现菜单：
     * 3.1 语文
     * 3.2 数学
     * 3.3 总分
     * @param: null
     * @return: void
     */
    public void getClassAverageScoreFather(){
        Scanner sc = new Scanner(System.in);
        //求班级平均分菜单
        while(true){//使用while循环实现多次选择
            boolean flag=false;//用于判断是否跳出循环(一般初始化都为false)
            welcomeSelStuAverage();//配合班级平均分欢迎界面给用户提供提示服务
            int ch=sc.nextInt();//输入一个整数选择相应的操作
            switch (ch){
                case 1:
                    //3.1 求该班级语文平均分
                    System.out.println("请输入要求语文平均成绩的班级(样例:一年级1班)：");
                    String myClass1=sc.next();
                    double chineseAver =getClassChineseAverage(myClass1);
                    if(chineseAver <0){
                        System.out.println("您输入的指定班级错误，请重新输入班级！");
                    }
                    else{
                        System.out.println(myClass1+"的学生平均语文成绩为："+ chineseAver);
                    }
                    break;
                case 2:
                    //3.2 求该班级数学平均分
                    System.out.println("请输入要求数学平均成绩的班级(样例:一年级1班)：");
                    String myClass2=sc.next();
                    double mathAver =getClassMathAverage(myClass2);
                    if(mathAver <0){
                        System.out.println("您输入的指定班级错误，请重新输入班级！");
                    }
                    else{
                        System.out.println(myClass2+"的学生平均数学成绩为："+ mathAver);
                    }
                    break;
                case 3:
                    //3.3 求该班级总分(语文+数学)平均分
                    System.out.println("请输入要求总分(语文+数学)平均成绩的班级(样例:一年级1班)：");
                    String myClass3 =sc.next();
                    double totalAver =getClassTotalAverage(myClass3);
                    if(totalAver <0){
                        System.out.println("您输入的指定班级错误，请重新输入班级！");
                    }
                    else{
                        System.out.println(myClass3 +"的学生平均总分(语文+数学)成绩为："+ totalAver);
                    }
                    break;
                case 0:
                    flag=true;//确定结束该子功能界面
                    break;
                default:
                    System.out.println("输入错误，请选择正确的功能序号!");
            }
            if(flag){//如果flag为真那么就跳出while回到主菜单中的switch中去(关键)
                System.out.println("已退出求班级平均分界面,回到首页！！");
                break;
            }
        }
    }


    /**
     * @description: 4.求不及格的学生的父功能方法
     *  4.1 语文不及格(按班级)
     *  4.2 数学不及格(按班级)
     *  4.3 总分不及格(按班级)
     * @param: null
     * @return:
     */
    public void SelStudentIsFailFather(){
        Scanner sc = new Scanner(System.in);
        //求不及格的学生菜单
        while(true){//使用while循环实现多次选择
            boolean flag=false;//用于判断是否跳出循环(一般初始化都为false)
            welcomeStuFail();//配合不及格的学生欢迎界面给用户提供提示服务
            int ch=sc.nextInt();//输入一个整数选择相应的操作
            switch (ch){
                case 1:
                    //4.1 求语文不及格的人数和学生信息(按班级)
                    System.out.println("请输入要统计语文成绩不及格学生的班级(样例:一年级1班)：");
                    String myClass1=sc.next();
                    int ChineseFail =getStudentByChineseFail(myClass1);
                    if(ChineseFail <0){
                        System.out.println("您输入的指定班级错误，请重新输入班级！");
                    }
                    else{
                        System.out.println(myClass1 +"的学生语文成绩不及格的学生人数为："+ ChineseFail);
                    }
                    break;
                case 2:
                    //4.2 求数学不及格的人数和学生信息(按班级)
                    System.out.println("请输入要统计数学成绩不及格学生的班级(样例:一年级1班)：");
                    String myClass2 =sc.next();
                    int mathFail =getStudentByMathFail(myClass2);
                    if(mathFail <0){
                        System.out.println("您输入的指定班级错误，请重新输入班级！");
                    }
                    else{
                        System.out.println(myClass2 +"的学生数学成绩不及格的学生人数为："+ mathFail);
                    }
                    break;
                case 3:
                    //4.3 求总分(语文+数学)不及格的人数和学生信息(按班级)
                    System.out.println("请输入要统计总分(语文+数学)不及格学生的班级(样例:一年级1班)：");
                    String myClass3 =sc.next();
                    int totalFail =getStudentByTotalFail(myClass3);
                    if(totalFail <0){
                        System.out.println("您输入的指定班级错误，请重新输入班级！");
                    }
                    else{
                        System.out.println(myClass3 +"的学生总分(语文+数学)不及格的学生人数为："+ totalFail);
                    }
                    break;
                case 0:
                    flag=true;//确定结束该子功能界面
                    break;
                default:
                    System.out.println("输入错误，请选择正确的功能序号!");
            }
            if(flag){//如果flag为真那么就跳出while回到主菜单中的switch中去(关键)
                System.out.println("已退出求不及格的学生人数界面,回到首页！！");
                break;
            }
        }
    }



    /**
     * @description: 5.修改学生成绩的父功能方法
     * 5.1 按学号修改语文成绩
     * 5.2 按学号修改数学成绩
     * @param: null
     * @return: void
     */
    public void updateStudentScoreFather(){
        Scanner sc = new Scanner(System.in);
        //修改学生成绩菜单
        while(true){//使用while循环实现多次选择
            boolean flag=false;//用于判断是否跳出循环(一般初始化都为false)
            welcomeUpdate();//配合修改学生成绩欢迎界面给用户提供提示服务
            int ch=sc.nextInt();//输入一个整数选择相应的操作
            switch (ch){
                case 1:
                    //5.1 按学号修改对应学生语文成绩
                    System.out.println("请输入要修改的学生学号：");
                    String num1 = sc.next();
                    System.out.println("请输入修改值语文成绩：");
                    double chineseScore = sc.nextDouble();
                    System.out.println("\n修改前的结果如下(输入合法则显示修改前的数据or不合法查无此人)：");
                    //输出修改前的数据 而且用于判断无对应学号这个非法输入
                    Student s1 = getStudentByNum(num1);//学生数组中存的是每个学生的地址(引用)所以类型为Student
                    if (s1 == null) {
                        System.out.println("查无此人，请重新输入学号！否则无法修改");
                    } else {
                        System.out.println("输入合法(有此人) 显示修改前的数据如下");
                        s1.showInfo();
                    }
                    //修改
                    int index1 = updateStudentChineseScoreByNum(num1, chineseScore);
                    System.out.println("\n经过修改后结果如下：");
                    //如果返回false==>说明修改失败或者是没有指定学生 提示重新正确输入学号
                    if(index1 <0){
                        System.out.println("修改失败或者是没有指定学生，请重新正确输入学号！");
                    }else{//如果返回true==>说明修改成功 并输出新旧结果
                        System.out.println("修改成功 输出更改后新结果如下");
                        ss[index1].showInfo();
                    }
                    break;
                case 2:
                    //5.2 按学号修改对应学生数学成绩
                    System.out.println("请输入要修改的学生学号：");
                    String num2 = sc.next();
                    System.out.println("请输入修改值数学成绩：");
                    double mathScore = sc.nextDouble();
                    System.out.println("\n修改前的结果如下(输入合法则显示修改前的数据or不合法查无此人)：");
                    //输出修改前的数据 而且用于判断无对应学号这个非法输入
                    Student s2 = getStudentByNum(num2);//学生数组中存的是每个学生的地址(引用)所以类型为Student
                    if (s2 == null) {
                        System.out.println("查无此人，请重新输入学号！否则无法修改");
                    } else {
                        System.out.println("输入合法(有此人) 显示修改前的数据如下");
                        s2.showInfo();
                    }
                    //修改
                    int index2 = updateStudentMathScoreByNum(num2,mathScore);
                    System.out.println("\n经过修改后结果如下：");
                    //如果返回false==>说明修改失败或者是没有指定学生 提示重新正确输入学号
                    if(index2 <0){
                        System.out.println("修改失败或者是没有指定学生，请重新正确输入学号！");
                    }else{//如果返回true==>说明修改成功 并输出新旧结果
                        System.out.println("修改成功 输出更改后新结果如下");
                        ss[index2].showInfo();
                    }
                    break;
                case 0:
                    flag=true;//确定结束该子功能界面
                    break;
                default:
                    System.out.println("输入错误，请选择正确的功能序号!");
            }
            if(flag){//如果flag为真那么就跳出while回到主菜单中的switch中去(关键)
                System.out.println("已退出修改学生成绩界面,回到首页！！");
                break;
            }
        }
    }

    /**
     * @description: 6.考试系统的父功能方法
     * 6.1 统一考试成绩自动录入(Random)
     * 6.2 统一考试成绩手动录入(Scanner)
     * @param: null
     * @return: void
     */
    public void examSystemFather(){
        Scanner sc = new Scanner(System.in);
        //考试系统菜单
        while(true){//使用while循环实现多次选择
            boolean flag=false;//用于判断是否跳出循环(一般初始化都为false)
           welcomeExamSystem();//配合考试系统欢迎界面给用户提供提示服务
            int ch=sc.nextInt();//输入一个整数选择相应的操作
            switch (ch){
                case 1:
                    //6.1 统一考试成绩自动录入(Random)
                    examinationSystemByRandom();//对小学生进行考试成绩的自动录入
                    break;
                case 2:
                    //6.2 统一考试成绩手动录入(Scanner)
                    examinationSystemByScanner();//对小学生进行考试成绩的手动录入
                    break;
                case 0:
                    flag=true;//确定结束该子功能界面
                    break;
                default:
                    System.out.println("输入错误，请选择正确的功能序号!");
            }
            if(flag){//如果flag为真那么就跳出while回到主菜单中的switch中去(关键)
                System.out.println("已退出考试系统界面,回到首页！！1");
                break;
            }
        }
    }

/*--------------------------------------END---------------------------------------*/

/*--------------------------------父功能菜单-----------------------------------*/

    /**
     * @description: 人机交互界面(菜单界面) 主要用于实现系统与用户的交互
     * @param: null
     * @return: void
     */
    public void menu(){
        //输入
        Scanner sc = new Scanner(System.in);
        while(true){//使用while循环实现多次选择
            welcomeOfFather();//配合夫功能欢迎界面给用户提供提示服务
            int ch=sc.nextInt();//输入一个整数选择相应的操作
            switch (ch){
                case 1:
                    //1.显示学生信息(父功能)
                    showAllStudentsFather();
                    break;
                case 2:
                    //2.查询指定学生信息(父功能)
                    getStudentFather();
                    break;
                case 3:
                    // 3.求班级平均分(父功能)
                    getClassAverageScoreFather();
                    break;
                case 4:
                    // 4.求不及格的学生(父功能)
                    SelStudentIsFailFather();
                    break;
                case 5:
                    //5.修改学生成绩(父功能)
                    updateStudentScoreFather();
                    break;
                case 6:
                    //考试成绩(父功能)
                    examSystemFather();
                    break;
                case 0:
                    System.out.println("-----再见，欢迎下次再来-----");
                    System.exit(0);
                    break;
                default:
                    System.out.println("输入错误，请选择正确的功能序号!");
            }
        }
    }
/*----------------------------------END-------------------------------------*/


/*--------------------------------考试系统-----------------------------------*/

    /**
     * 考试系统的背景：
     * private double mathScore;//数学成绩
     * private double chineseScore;//语文成绩
     * private double TotalScore;//总分成绩(语文+数学)
     * 由于成绩是在参加考试后才产生的
     * 因此在创建对象时无法对成绩初始化 我们需要设置一个考试系统来处理以上三个成绩信息
     *
     */

    /**
     * @description: 考试系统成绩的初始化 1.通过Random类对全校的学生进行统一考试成绩录入
     * 借助随机类Random产生随机成绩
     * @param: null
     * @return: void
     */
    //扩充
    public void examinationSystemByRandom(){
        Random r=new Random();
        for (int i = 0; i < ss.length; i++) {
            double mathScore=r.nextInt(101);//产生随机数学成绩(0-100)
            double chineseScore=r.nextInt(101);//产生随机语文成绩(0-100)
            ss[i].setChineseScore(chineseScore);
            ss[i].setMathScore(mathScore);
            ss[i].setTotalScore(mathScore+chineseScore);
        }
        System.out.println("考试成绩录入成功(Random)！！");
    }

    /**
     * @description: 2.通过手动输入全校学生的成绩存于表中
     * @param: null
     * @return: void
     */
    //扩充
    public void examinationSystemByScanner(){
        /* 测试数据
         * 学生    语文成绩  数学成绩
         * 学生 1:  85.5     90.2
         * 学生 2:  78.8     88.5
         * 学生 3:  92.1     95.3
         * 学生 4:  81.2     81.2
         * 学生 5:  76.9     82.1
         * 学生 6:  89.3     91.8
         * 学生 7:  72.5     78.6
         * 学生 8:  86.7     90.1
         * 学生 9:  79.1     83.2
         * 学生 10: 83.8     87.4
         */
        Scanner sc=new Scanner(System.in);
        System.out.println("手动录入学生信息：");
        for (int i = 0; i < ss.length; i++) {
            System.out.println("请输入第"+(i+1)+"个学生语文成绩");
            double chineseScore=sc.nextDouble();//输入语文成绩
            ss[i].setChineseScore(chineseScore);

            System.out.println("请输入第"+(i+1)+"个学生数学成绩");
            double mathScore=sc.nextDouble();//输入数学成绩
            ss[i].setMathScore(mathScore);
            System.out.println("第"+(i+1)+"个学生数学成绩录入成功！\n");

            ss[i].setTotalScore(mathScore+chineseScore);//录入总分成绩
            System.out.println("第"+(i+1)+"个学生总分成绩录入成功！\n");
        }
        System.out.println("考试成绩录入成功(Scanner)！！");
    }
/*----------------------------------END-------------------------------------*/
}
